package cn.xiyun.xiyuncc.service.impl;


import ch.qos.logback.core.joran.action.ActionUtil;
import cn.xiyun.xiyuncc.domain.*;
import cn.xiyun.xiyuncc.dto.CourseSaveDto;
import cn.xiyun.xiyuncc.dto.CourseSearchDto;
import cn.xiyun.xiyuncc.dto.KillOrderDto;
import cn.xiyun.xiyuncc.exception.OperationException;
import cn.xiyun.xiyuncc.feignClient.MediaFeignClient;
import cn.xiyun.xiyuncc.feignClient.SearchFeignClient;
import cn.xiyun.xiyuncc.feignClient.UserFeignClient;
import cn.xiyun.xiyuncc.mapper.CourseMapper;
import cn.xiyun.xiyuncc.result.JSONResult;
import cn.xiyun.xiyuncc.service.*;
import cn.xiyun.xiyuncc.util.AssertUtil;
import cn.xiyun.xiyuncc.vo.CourseInfoVO;
import cn.xiyun.xiyuncc.vo.DetailDataVO;
import cn.xiyun.xiyuncc.vo.OrderDataVO;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xiyun.maple
 * @since 2023-03-11
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Autowired
    private SearchFeignClient searchFeignClient;
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private ICourseDetailService ICourseDetailService;
    @Autowired
    private ICourseMarketService courseMarketService;
    @Autowired
    private ICourseResourceService courseResourceService;
    @Autowired
    private ICourseTeacherService courseTeacherService;
    @Autowired
    private ICourseSummaryService courseSummaryService;
    @Autowired
    private ICourseDetailService courseDetailService;
    @Autowired
    private ICourseChapterService courseChapterService;
    @Autowired
    private ICourseUserLearnService courseUserLearnService;

    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private MediaFeignClient mediaFeignClient;

    /**
     * 新增课程
     *
     * @param courseSaveDto
     */
    @Override
    public void courseAddition(CourseSaveDto courseSaveDto) {
        Course course = courseSaveDto.getCourse();

        // TODO 循环查询需要改进
        String s = new String();
        Long[] teacharIds = courseSaveDto.getTeacharIds();
        List<Teacher> teachers = teacherService.selectBatchIds(Arrays.asList(teacharIds));
        for (Teacher teacher : teachers) {
            s = s + teacher.getName() + ",";
        }
       /* for (int i = 0; i < teacharIds.length; i++) {

            Teacher teacher = teacherService.selectById(teacharIds[i]);
                s= s + teacher.getName()+",";
        }*/
        //长度-1
        s = s.substring(0, s.length() - 1);
        course.setTeacherNames(s);
        course.setStatus(0);
        // course.setCourseRecommended(0);

        // TODO 登陆人信息待定
        course.setLoginUserName("暂无");
        course.setLoginId(1L);
        // 添加到课程
        super.insert(course);
        //获取 课程id
        Long courseId = course.getId();

        //课程详情
        CourseDetail courseDetail = courseSaveDto.getCourseDetail();
        courseDetail.setId(courseId);
        // 添加课程详情
        ICourseDetailService.insert(courseDetail);

        // 课程售卖
        CourseMarket courseMarket = courseSaveDto.getCourseMarket();
        courseMarket.setId(courseId);
        // 添加课程售卖信息
        courseMarketService.insert(courseMarket);

        // 课程资源
        CourseResource resources = courseSaveDto.getCourseResource();
        resources.setCourseId(courseId);
        resources.setType(0);
        courseResourceService.insert(resources);

        // 课程数据course_summary
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(courseId);
        courseSummary.setCommentCount(0);
        courseSummary.setSaleCount(0);
        courseSummary.setViewCount(0);
        courseSummaryService.insert(courseSummary);

        //课程与教师中间表添加数据
        CourseTeacher courseTeacher = new CourseTeacher();
        for (Long teacharId : teacharIds) {
            courseTeacher.setCourseId(courseId);
            courseTeacher.setTeacherId(teacharId);
            courseTeacherService.insert(courseTeacher);
        }
    }

    /**
     * 课程上架
     *
     * @param id
     */
    @Override
    public void onLineCourse(Long id) {
        Course course = super.selectById(id);
        CourseMarket courseMarket = courseMarketService.selectById(id);
        CourseSummary courseSummary = courseSummaryService.selectById(id);

        CourseSearchDto courseSearchDto = new CourseSearchDto();
        BeanUtils.copyProperties(course, courseSearchDto);
        BeanUtils.copyProperties(courseMarket, courseSearchDto);
        BeanUtils.copyProperties(courseSummary, courseSearchDto);
        String s = "免费";
        String st = "收费";
        courseSearchDto.setChargeName(courseMarket.getCharge() == 1 ? s : st);
        // 将课程信息添加到es
        searchFeignClient.courseSearchSave(courseSearchDto);
        // 修改课程的状态为上架,加入上架时间
        course.setStatus(1);
        course.setOnlineTime(new Date());
        EntityWrapper<Course> wrapper = new EntityWrapper<>();
        wrapper.eq("id", course.getId());
        super.update(course, wrapper);
        // 发送站内信
        rocketMQTemplate.syncSend("STATION_MESSAGE:COURSE_SHELVING",
                MessageBuilder.withPayload("userIds").build());
    }

    /**
     * 课程详情展示
     *
     * @param id 课程id
     * @return
     */
    @Override
    public DetailDataVO detailData(Long id) {
        AssertUtil.isNotNull(id, "课程不存在");
        Course course = super.selectById(id);
        AssertUtil.isEquals(course.getStatus().toString(), "1", "课程已下架");
        // 查询课程价格
        CourseMarket courseMarket = courseMarketService.selectById(id);
        // 查询课程详情
        CourseDetail courseDetail = courseDetailService.selectById(id);
        // 查询课程浏览量
        CourseSummary courseSummary = courseSummaryService.selectById(id);
        // 查询课程讲师信息
        List<Teacher> teachers = teacherService.courseTeacher(id);
        // 查询课程章节
        Wrapper<CourseChapter> wrapperChapter = new EntityWrapper<>();
        wrapperChapter.eq("course_id", id);
        List<CourseChapter> courseChapters = courseChapterService.selectList(wrapperChapter);

        // 课程服务获取课程视频资源
        JSONResult jsonResult = mediaFeignClient.chapterMediaFile(id);
        AssertUtil.isTrue(jsonResult.isSuccess(), "视频资源服务器繁忙");
        // 获取课程视频资源集合
        List<MediaFile> mediaFiles = JSON.parseArray(JSON.toJSONString(jsonResult.getData()), MediaFile.class);
        // 创建Map集合
        //Map<Long, MediaFile> collect = mediaFiles.stream().collect(Collectors.toMap(MediaFile::getId, mediaFile -> mediaFile));
        courseChapters.forEach(courseChapter -> {
            mediaFiles.forEach(mediaFile -> {
                if (courseChapter.getId().equals(mediaFile.getChapterId())) {
                    mediaFile.setFileUrl("");
                    courseChapter.getMediaFileList().add(mediaFile);
                }
            });

        });
        DetailDataVO detailDataVO = new DetailDataVO(course, courseMarket, courseDetail, courseSummary, teachers, courseChapters);
        return detailDataVO;
    }

    /**
     * 获取视频数据
     *
     * @param id
     * @return
     */
    @Override
    public String getForUser(Long id) {
        // 根据id 获取课程信息
        JSONResult jsonResult = mediaFeignClient.get(id);
        AssertUtil.isTrue(jsonResult.isSuccess(), "视频资源服务器繁忙");
        AssertUtil.isNotNull(jsonResult.getData(), "资源异常");
        // 获取课程视频资源集合
        MediaFile mediaFile = JSON.parseObject(JSON.toJSONString(jsonResult.getData()), MediaFile.class);
        //查询课程销售表
        CourseMarket courseMarket = courseMarketService.selectById(mediaFile.getCourseId());
        // 课程是否免费
        if (courseMarket.getCharge() == 1) {
            return mediaFile.getFileUrl();
        }
        // 是否是试看
        if (mediaFile.getFree()) {
            return mediaFile.getFileUrl();
        }
        // @TODO 获取当前登陆人信息
        Long loginId = 3L;
        //=============================
        Wrapper<CourseUserLearn> wrapper = new EntityWrapper<>();
        wrapper.eq("login_id", loginId).and().eq("course_id", mediaFile.getCourseId());
        // 根据用户id与课程id查询用户购买课程表
        CourseUserLearn courseUserLearn = courseUserLearnService.selectOne(wrapper);
        AssertUtil.isNotNull(courseUserLearn, "课程为付费课程");
        // 判断是否过期
        boolean after = new Date().after(courseUserLearn.getEndTime());
        AssertUtil.isFalse(after, "课程已过期,请重新购买");
        return mediaFile.getFileUrl();
    }

    /**
     * 课程 订单信息
     * @param
     * @return
     */
    @Override
    public OrderDataVO orderData(String ids) {
        AssertUtil.isNotNull(ids,"参数异常");
        String[] split = ids.split(",");
        List<String> strings = Arrays.asList(split);
        // 获取课程数据
        List<Course> courses = super.selectBatchIds(strings);
        if(split.length!=courses.size()){
            throw new OperationException("参数异常");
        }
        // 获取课程销售表数据
        List<CourseMarket> courseMarkets = courseMarketService.selectBatchIds(strings);
        // 课程销售表数据转为Map
        Map<Long, CourseMarket> collect = courseMarkets.stream().collect(Collectors.toMap(CourseMarket::getId, courseMarket -> courseMarket));
        // 返回前端的订单信息
        OrderDataVO orderDataVO = new OrderDataVO();
        // 合计价格
        BigDecimal bigDecimal = new BigDecimal("0");
        for (Course course : courses) {
            if(course.getStatus() !=  1){
                throw new OperationException("课程未上架");
            }
            // 根据id获取销售表数据
            CourseMarket courseMarket = collect.get(course.getId());
            CourseInfoVO courseInfoVO = new CourseInfoVO(course,courseMarket,1);
            // 赋值
            bigDecimal = bigDecimal.add(courseMarket.getPrice());
            // 放入订单信息中
            orderDataVO.getCourseInfos().add(courseInfoVO);
        }
        orderDataVO.setTotalAmount(bigDecimal);

        return orderDataVO;
    }

    /**
     * 秒杀订单信息
     * @param orderNo
     * @return
     */
    @Override
    public OrderDataVO orderKillData(String orderNo) {
        // 查询redis中 的秒杀预订单
        Object o = redisTemplate.opsForValue().get(orderNo);
        KillOrderDto killOrderDto = (KillOrderDto) o;
        OrderDataVO orderDataVO = orderData(killOrderDto.getCourseId().toString());
        orderDataVO.setTotalAmount(killOrderDto.getKillPrice());
        return orderDataVO;
    }


}
